package com.tingyukeji.fastpay.sport.ui.activity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.Polygon;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.trace.LBSTraceClient;
import com.amap.api.trace.TraceListener;
import com.amap.api.trace.TraceLocation;
import com.amap.api.trace.TraceOverlay;
import com.tingyukeji.fastpay.R;
import com.tingyukeji.fastpay.base.BaseActivity;
import com.tingyukeji.fastpay.databinding.ActivityRecordMapBinding;
import com.tingyukeji.fastpay.sport.adapter.DbAdapter;
import com.tingyukeji.fastpay.sport.model.PathRecord;
import com.tingyukeji.fastpay.sport.view.CountdownDialog;
import com.tingyukeji.fastpay.sport.view.RunStopButtonView;
import com.tingyukeji.fastpay.utils.MapUtils;
import com.tingyukeji.fastpay.utils.TimeUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class RecordMapActivity extends BaseActivity implements LocationSource,
        AMapLocationListener, TraceListener, AMap.OnMapClickListener{
    private ActivityRecordMapBinding binding;
    private AMap mAMap;
    private PathRecord record;
    private long mStartTime;
    private long mEndTime;
    private List<Polygon> polygonList = new ArrayList<>();
    private List<Marker> markerList = new ArrayList<>();
    private TraceOverlay mTraceoverlay;
    private List<TraceOverlay> mOverlayList = new ArrayList<TraceOverlay>();
    private PolylineOptions mPolyoptions, tracePolytion;
    private Marker mlocMarker;
    private int mDistance = 0;
    private double distance = 0;
    private int tracesize = 30;
    private LocationSource.OnLocationChangedListener mListener;
    private AMapLocationClient mLocationClient;
    private AMapLocationClientOption mLocationOption;
    private List<TraceLocation> mTracelocationlist = new ArrayList<TraceLocation>();
    private Polyline mpolyline;
    private DbAdapter DbHepler;
    private Timer mTimer;
    private boolean mRuning = false;
    private long startTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_record_map);
        binding.map.onCreate(savedInstanceState);// 此方法必须重写
        initData();
    }

    private void initData() {
        if (mAMap == null) {
            mAMap = binding.map.getMap();
            setMapCustomStyleFile(this);
            mAMap.setMapCustomEnable(true);
            setUpMap();
        }
        binding.tvPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /*CountdownDialog dialog = CountdownDialog.newInstance();
                dialog.show(getSupportFragmentManager(),"dialog");
                dialog.setListener(new CountdownDialog.OnClickListener() {
                    @Override
                    public void click(String message) {
                    }

                    @Override
                    public void finish() {
                        mRuning = true;
                        binding.tvPause.setVisibility(View.GONE);
                        binding.rlStop.setVisibility(View.VISIBLE);
                        binding.tvContinue.setVisibility(View.VISIBLE);
                        binding.tvContinue.setText("暂停");
                        mAMap.clear(true);
                        if (record != null) {
                            record = null;
                        }
                        record = new PathRecord();
                        mStartTime = System.currentTimeMillis();
                        startTime = System.currentTimeMillis();
                        record.setDate(getcueDate(mStartTime));
                        binding.tvRunTime.setText(TimeUtils.getDValue(startTime,TimeUtils.getStopTime(binding.tvRunTime.getText().toString())));
                        startTime();
                    }
                });*/
                mRuning = true;
                binding.tvPause.setVisibility(View.GONE);
                binding.rlStop.setVisibility(View.VISIBLE);
                binding.tvContinue.setVisibility(View.VISIBLE);
                startTime = System.currentTimeMillis() - TimeUtils.getStopTime(binding.tvRunTime.getText().toString());
//                    binding.tvRunTime.setText(TimeUtils.getDValue(startTime,TimeUtils.getStopTime(binding.tvRunTime.getText().toString())));
                startTime();

            }
        });
        binding.tvContinue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mRuning = false;
                binding.tvPause.setVisibility(View.VISIBLE);
                binding.rlStop.setVisibility(View.GONE);
                binding.tvContinue.setVisibility(View.GONE);
                mTimer.cancel();
                mTimer = null;
//                long test = TimeUtils.getStopTime(binding.tvRunTime.getText().toString());
                /*if ("暂停".equals(binding.tvContinue.getText().toString())){
                    mRuning = false;
                    binding.tvContinue.setText("继续");
                    mTimer.cancel();
                    mTimer = null;
                    long test = TimeUtils.getStopTime(binding.tvRunTime.getText().toString());
                }else {
                    mRuning = true;
                    binding.tvContinue.setText("暂停");
                    startTime = System.currentTimeMillis() - TimeUtils.getStopTime(binding.tvRunTime.getText().toString());
//                    binding.tvRunTime.setText(TimeUtils.getDValue(startTime,TimeUtils.getStopTime(binding.tvRunTime.getText().toString())));
                    startTime();
                }*/
            }
        });

        binding.rsbStop.setOnLongClickListener(new RunStopButtonView.OnLongClickListener() {
            @Override
            public void onLongClick() {
                //开始录制
//                Log.e("yufs","开始录制");
            }

            @Override
            public void onNoMinRecord(int minTime) {
//                Toast.makeText(MainActivity.this, "录制最短时间为"+minTime+"s", Toast.LENGTH_SHORT).show();
//                Log.e("yufs","录制时间太短");
            }

            @Override
            public void onRecordFinishedListener() {
//                Toast.makeText(MainActivity.this, "录制完成", Toast.LENGTH_SHORT).show();
//                Log.e("yufs","录制完成");
                mRuning = false;
                binding.rlStop.setVisibility(View.GONE);
                binding.tvContinue.setVisibility(View.GONE);
                binding.tvPause.setVisibility(View.VISIBLE);
                mEndTime = System.currentTimeMillis();
                mOverlayList.add(mTraceoverlay);
                saveRecord(record.getPathline(), record.getDate());
            }
        });
        binding.titleLlyRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                record();
            }
        });
        mTraceoverlay = new TraceOverlay(mAMap);
        mTimer = new Timer();
        startRun();
    }

    private void startRun() {
        CountdownDialog dialog = CountdownDialog.newInstance();
        dialog.show(getSupportFragmentManager(),"dialog");
        dialog.setListener(new CountdownDialog.OnClickListener() {
            @Override
            public void click(String message) {
            }

            @Override
            public void finish() {
                mRuning = true;
                binding.tvPause.setVisibility(View.VISIBLE);
                binding.rlStop.setVisibility(View.GONE);
                binding.tvContinue.setVisibility(View.GONE);
                mAMap.clear(true);
                if (record != null) {
                    record = null;
                }
                record = new PathRecord();
                mStartTime = System.currentTimeMillis();
                startTime = System.currentTimeMillis();
                record.setDate(getcueDate(mStartTime));
                binding.tvRunTime.setText(TimeUtils.getDValue(startTime,TimeUtils.getStopTime(binding.tvRunTime.getText().toString())));
                startTime();
            }
        });
    }

    private void setMapCustomStyleFile(Context context) {
        String styleName = "style.data";
        FileOutputStream outputStream = null;
        InputStream inputStream = null;
        String filePath = null;
        try {
            inputStream = context.getAssets().open(styleName);
            byte[] b = new byte[inputStream.available()];
            inputStream.read(b);

            filePath = context.getFilesDir().getAbsolutePath();
            File file = new File(filePath + "/" + styleName);
            if (file.exists()) {
                file.delete();
            }
            file.createNewFile();
            outputStream = new FileOutputStream(file);
            outputStream.write(b);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null)
                    inputStream.close();

                if (outputStream != null)
                    outputStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        mAMap.setCustomMapStylePath(filePath + "/" + styleName);
        mAMap.showMapText(true);
    }

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        mAMap.getUiSettings().setTiltGesturesEnabled(false);
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));// 设置圆形的边框颜色
        myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));// 设置圆形的填充颜色
        mAMap.setMyLocationStyle(myLocationStyle);
        mAMap.setLocationSource(this);// 设置定位监听
        mAMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        mAMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        // 设置定位的类型为定位模式 ，可以由定位、跟随或地图根据面向方向旋转几种
        mAMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
        mAMap.setOnMapClickListener(this);
        mAMap.moveCamera(CameraUpdateFactory.zoomTo(17));
        mAMap.moveCamera(CameraUpdateFactory.changeTilt(30));
    }

    protected void saveRecord(List<AMapLocation> list, String time) {
        if (list != null && list.size() > 0 && getDistance(list) > 0) {
            DbHepler = new DbAdapter(this);
            DbHepler.open();
            String duration = getDuration();
            float distance = getDistance(list);
            String average = getAverage(distance);
            String pathlineSring = getPathLineString(list);
            AMapLocation firstLocaiton = list.get(0);
            AMapLocation lastLocaiton = list.get(list.size() - 1);
            String stratpoint = amapLocationToString(firstLocaiton);
            String endpoint = amapLocationToString(lastLocaiton);
            DbHepler.createrecord(String.valueOf(distance), duration, average,
                    pathlineSring, stratpoint, endpoint, time);
            DbHepler.close();
            Bundle bundle = new Bundle();
            bundle.putFloat("distance",distance);
            bundle.putString("duration",duration);
            bundle.putString("time",time);
            bundle.putParcelableArrayList("list", (ArrayList<? extends Parcelable>) list);
            bundle.putParcelable("firstLocaiton",firstLocaiton);
            bundle.putParcelable("lastLocaiton",lastLocaiton);
            goActivity(RunRecordActivity.class,bundle);
        } else {
            Toast.makeText(this, "没有记录到路径", Toast.LENGTH_SHORT)
                    .show();
        }
        finish();
    }

    @SuppressLint("SimpleDateFormat")
    private String getcueDate(long time) {
        SimpleDateFormat formatter = new SimpleDateFormat(
                "yyyy-MM-dd  HH:mm:ss ");
        Date curDate = new Date(time);
        String date = formatter.format(curDate);
        return date;
    }

    /**
     * 最后获取总距离
     * @return
     */
    private int getTotalDistance() {
        int distance = 0;
        for (TraceOverlay to : mOverlayList) {
            distance = distance + to.getDistance();
        }
        return distance;
    }

    /**
     * 定位结果回调
     * @param amapLocation 位置信息类
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null && amapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
                LatLng mylocation = new LatLng(amapLocation.getLatitude(),
                        amapLocation.getLongitude());
				mAMap.moveCamera(CameraUpdateFactory.changeLatLng(mylocation));
                if (mRuning) {
                    if (null != record && null != record.getPathline() && record.getPathline().size() > 0){
                        AMapLocation previousAmapLocation = record.getPathline().get(record.getPathline().size()-1);
                        LatLng previousLocation = new LatLng(previousAmapLocation.getLatitude(),
                                previousAmapLocation.getLongitude());
                        distance = distance + AMapUtils.calculateLineDistance(previousLocation, mylocation);
                        binding.showAllDis.setText(new DecimalFormat("#0.00").format(distance / 1000d) + "km");
                    }else {
                        binding.showAllDis.setText("0.00km");
                    }
                    record.addpoint(amapLocation);
                    if (null == mPolyoptions){
                        mPolyoptions = new PolylineOptions();
                    }else {
                        mPolyoptions.add(mylocation);
                    }
                    mTracelocationlist.add(MapUtils.parseTraceLocation(amapLocation));
                    redrawline();
                    if (mTracelocationlist.size() > tracesize - 1) {
                        trace();
                    }
                }
            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": "
                        + amapLocation.getErrorInfo();
            }
        }
    }

    @Override
    public void onMapClick(LatLng latLng) {
//        Marker marker = mAMap.addMarker(new MarkerOptions().position(latLng));
//        marker.setDraggable(true);//设置Marker可拖动
//        marker.setFlat(true);
//        markerList.add(marker);
//        for (Polygon p : polygonList) {
//            if (p.contains(latLng)){
//                Toast.makeText(this, "点击了" + p.getId() +"围栏块", Toast.LENGTH_SHORT).show();
//                return;
//            }
//        }
    }

    @Override
    public void activate(LocationSource.OnLocationChangedListener listener) {
        mListener = listener;
        startlocation();
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();

        }
        mLocationClient = null;
    }

    /**
     * 轨迹纠偏失败回调。
     * @param i
     * @param s
     */
    @Override
    public void onRequestFailed(int i, String s) {
        mOverlayList.add(mTraceoverlay);
        mTraceoverlay = new TraceOverlay(mAMap);
    }

    @Override
    public void onTraceProcessing(int i, int i1, List<LatLng> list) {

    }

    /**
     * 轨迹纠偏成功回调。
     * @param lineID 纠偏的线路ID
     * @param linepoints 纠偏结果
     * @param distance 总距离
     * @param waitingtime 等待时间
     */
    @Override
    public void onFinished(int lineID, List<LatLng> linepoints, int distance, int waitingtime) {
        if (lineID == 1) {
            if (linepoints != null && linepoints.size()>0) {
                mTraceoverlay.add(linepoints);
                mDistance += distance;
                mTraceoverlay.setDistance(mTraceoverlay.getDistance()+distance);
                if (mlocMarker == null) {
                    mlocMarker = mAMap.addMarker(new MarkerOptions().position(linepoints.get(linepoints.size() - 1))
                            .icon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.point))
                            .title("距离：" + mDistance+"米"));
                    mlocMarker.showInfoWindow();
                } else {
                    mlocMarker.setTitle("距离：" + mDistance+"米");
                    Toast.makeText(this, "距离"+mDistance, Toast.LENGTH_SHORT).show();
                    mlocMarker.setPosition(linepoints.get(linepoints.size() - 1));
                    mlocMarker.showInfoWindow();
                }
            }
        } else if (lineID == 2) {
            if (linepoints != null && linepoints.size()>0) {
                mAMap.addPolyline(new PolylineOptions()
                        .color(Color.RED)
                        .width(40).addAll(linepoints));
            }
        }

    }

    /**
     * 开始定位。
     */
    private void startlocation() {
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            // 设置定位监听
            mLocationClient.setLocationListener(this);
            // 设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);

            mLocationOption.setInterval(2000);

//			mLocationOption.setOnceLocation(true);
            // 设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mLocationClient.startLocation();

        }
    }

    /**
     * 实时轨迹画线
     */
    private void redrawline() {
        if (mPolyoptions.getPoints().size() > 1) {
            if (mpolyline != null) {
                mpolyline.setPoints(mPolyoptions.getPoints());
            } else {
                mpolyline = mAMap.addPolyline(mPolyoptions);
            }
        }
//		if (mpolyline != null) {
//			mpolyline.remove();
//		}
//		mPolyoptions.visible(true);
//		mpolyline = mAMap.addPolyline(mPolyoptions);
//			PolylineOptions newpoly = new PolylineOptions();
//			mpolyline = mAMap.addPolyline(newpoly.addAll(mPolyoptions.getPoints()));
//		}
    }

    private void trace() {
        List<TraceLocation> locationList = new ArrayList<>(mTracelocationlist);
        LBSTraceClient mTraceClient = new LBSTraceClient(getApplicationContext());
//        mTraceClient.queryProcessedTrace(1, locationList, LBSTraceClient.TYPE_AMAP, this);
        TraceLocation lastlocation = mTracelocationlist.get(mTracelocationlist.size()-1);
        mTracelocationlist.clear();
        mTracelocationlist.add(lastlocation);
    }

    private String getDuration() {
        return String.valueOf((mEndTime - mStartTime) / 1000f);
    }

    private float getDistance(List<AMapLocation> list) {
        float distance = 0;
        if (list == null || list.size() == 0) {
            return distance;
        }
        for (int i = 0; i < list.size() - 1; i++) {
            AMapLocation firstpoint = list.get(i);
            AMapLocation secondpoint = list.get(i + 1);
            LatLng firstLatLng = new LatLng(firstpoint.getLatitude(),
                    firstpoint.getLongitude());
            LatLng secondLatLng = new LatLng(secondpoint.getLatitude(),
                    secondpoint.getLongitude());
            double betweenDis = AMapUtils.calculateLineDistance(firstLatLng,
                    secondLatLng);
            distance = (float) (distance + betweenDis);
        }
        return distance;
    }

    private String getAverage(float distance) {
        return String.valueOf(distance / (float) (mEndTime - mStartTime));
    }

    private String getPathLineString(List<AMapLocation> list) {
        if (list == null || list.size() == 0) {
            return "";
        }
        StringBuffer pathline = new StringBuffer();
        for (int i = 0; i < list.size(); i++) {
            AMapLocation location = list.get(i);
            String locString = amapLocationToString(location);
            pathline.append(locString).append(";");
        }
        String pathLineString = pathline.toString();
        pathLineString = pathLineString.substring(0,
                pathLineString.length() - 1);
        return pathLineString;
    }

    private String amapLocationToString(AMapLocation location) {
        StringBuffer locString = new StringBuffer();
        locString.append(location.getLatitude()).append(",");
        locString.append(location.getLongitude()).append(",");
        locString.append(location.getProvider()).append(",");
        locString.append(location.getTime()).append(",");
        locString.append(location.getSpeed()).append(",");
        locString.append(location.getBearing());
        return locString.toString();
    }

    private void record() {
        Intent intent = new Intent(this, RecordActivity.class);
        startActivity(intent);
    }

    @Override
    public void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        binding.map.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        binding.map.onSaveInstanceState(outState);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        binding.map.onDestroy();
        if (null != mTimer) mTimer.cancel();
        mTimer = null;
    }

    private void startTime(){
        if (null == mTimer){
            mTimer = new Timer();
        }
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                binding.tvRunTime.post(new Runnable() {
                    @Override
                    public void run() {
                        binding.tvRunTime.setText(TimeUtils.getDValue(startTime,0));
                    }
                });
            }
        }, 1000, 1000);
    }
}
